package com.neu.yth.nepBackend.member.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.neu.yth.nepBackend.auth.jwt.TokenUtils;
import com.neu.yth.nepBackend.entity.Member;
import com.neu.yth.nepBackend.entity.PageInfo;
import com.neu.yth.nepBackend.enums.ResponseEnum;
import com.neu.yth.nepBackend.member.mapper.MemberMapper;
import com.neu.yth.nepBackend.member.service.IMemberService;
import com.neu.yth.nepBackend.member.utils.Md5Tool;
import com.neu.yth.nepBackend.member.utils.SmsComponent;
import com.neu.yth.nepBackend.redis.config.RedisUtil;
import com.neu.yth.nepBackend.utils.Result;
import com.neu.yth.nepBackend.utils.VerifyCode;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

import java.util.Calendar;
import java.util.Date;
import java.util.List;

/**
 * <p>
 * 成员信息表（管理员、公众监督员、网格员） 服务实现类
 * </p>
 *
 * @author YTH
 * @since 2024-05-31
 */
@Service
public class MemberServiceImpl extends ServiceImpl<MemberMapper, Member> implements IMemberService {

    @Autowired
    private MemberMapper memberMapper;

    @Autowired
    private SmsComponent smsComponent;

    @Autowired
    private RedisUtil redisUtil;


    /**
     * 查询所有用户
     *
     * @return List<Member>
     */
    @Cacheable(value = "nep-members", key = "'nep-members'")
    @Override
    public Result<List<Member>> selectAll() {
        List<Member> mls = memberMapper.selectAll();
        return Result.success(mls);
    }

    /**
     * 公众监督员登录
     *
     * @param logInID
     * @param logInPwd
     * @return
     */
    @Override
    public Result<Member> login(String logInID, String logInPwd) {
        Member member = memberMapper.selectByNumber(logInID);
        if (member != null) {
            String md5 = Md5Tool.getMD5(logInPwd);
            if (member.getMemPwd().equals(md5)) {
                String token = TokenUtils.generateToken(member);
                redisUtil.set(logInID + "-token", token);
                member.setToken(token);
                member.setMemPwd(null);
                return Result.success(member);
            } else {
                return Result.fail(ResponseEnum.LOGIN_PASSWORD_ERROR);
            }
        } else {
            return Result.fail(ResponseEnum.LOGIN_NAME_NOT_EXIST);
        }
    }


    /**
     * 公众监督员注册
     * 注册成功，返回新成员唯一ID
     * 注册失败，返回-1
     *
     * @param member
     * @return
     */
    @Override
    public Result register(Member member) {
        if (member.getMemNumber() == null || member.getMemPwd() == null || member.getMemNumber().length() != 11) {
            return Result.fail(ResponseEnum.LOGIN_Number_OR_PWD_ERROR);
        }
        //检查number是否已经存在
        int count = memberMapper.selectCountByNumber(member.getMemNumber());
        if (count > 0) {
            // 账号已经存在
            return Result.fail(ResponseEnum.REGISTER_NAME_IN_USE);
        }

        try {
            member.setMemId(null);
            member.setMemState(1);
            member.setRoleId(3);
            member.setMemPwd(Md5Tool.getMD5(member.getMemPwd()));
            boolean flag = this.saveOrUpdate(member);
            if (flag) {
                return Result.success(member.getMemId());
            } else {
//              数据库插入失败
                return Result.fail(ResponseEnum.INSERT_FAILED);
            }
        } catch (Exception e) {
            return Result.fail(500, "注册失败——数据库插入异常", e.getMessage());
        }
    }

    /**
     * 公众监督员获取登录验证码
     *
     * @param tel
     * @return
     */
    @Override
    public Result getCode(String tel) {
        Member member = memberMapper.selectByNumber(tel);
        //检查number是否已经存在
        if (member == null) {
            return Result.fail(ResponseEnum.LOGIN_NAME_NOT_EXIST);
        }
        //生成验证码
        String code = VerifyCode.getCode();
        // 获取当前时间
        Calendar calendar = Calendar.getInstance();
        Date date = new Date(calendar.getTime().getTime());
        member.setMemNumber(tel);
        member.setVerifyCode(code);
        member.setCodeTime(date);
        redisUtil.set("smsCode", code, 5 * 60);
        try {
            //发送短信验证码()
            smsComponent.send(tel, code, 5);

            int count = memberMapper.updateById(member);
            if (count == 1) {
                return Result.success(member);
            } else {
                return Result.fail(ResponseEnum.LOGIN_VERIFY_CODE_ERROR);
            }
        } catch (Exception e) {
            return Result.fail(500, "验证码发送失败——数据库插入异常", e.getMessage());
        }
    }

    /**
     * 公众监督员验证码登录
     *
     * @param member
     * @return
     */
    @Override
    public Result loginCode(Member member) {

        Member mem = memberMapper.selectByNumber(member.getMemNumber());

        String token = TokenUtils.generateToken(mem);
        redisUtil.set(mem.getMemNumber() + "-token", token);

        if (mem == null) {
            return Result.fail(ResponseEnum.LOGIN_NAME_NOT_EXIST);
        }

        //获取时间
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.MINUTE, -5);

        if (member.getVerifyCode() == null || !member.getVerifyCode().equals(mem.getVerifyCode())) {
            return Result.fail(ResponseEnum.LOGIN_CODE_ERROR);
        } else if (mem.getCodeTime().before(new Date(calendar.getTime().getTime()))) {
            return Result.fail(ResponseEnum.LOGIN_CODE_TIMEOUT);
        } else {
            mem.setToken(TokenUtils.generateToken(mem));
            mem.setMemPwd(null);
            return Result.success(mem);
        }

    }

    /**
     * 分页查询
     *
     * @return
     */
    @Override
    public Result selectPage(PageInfo pageInfo) {
        Page<Member> page = new Page<>(pageInfo.getCurrentPage(), pageInfo.getPageSize());
        LambdaQueryWrapper<Member> wrapper = new LambdaQueryWrapper<>();
        wrapper.ne(Member::getMemState, 0);
        wrapper.ne(Member::getRoleId, 1);
        wrapper.ne(Member::getRoleId, 2);
        IPage<Member> iPage = memberMapper.selectPage(page, wrapper);
        return Result.success(iPage);
    }

    /**
     * 更新
     *
     * @param member
     * @return
     */
    @Override
    public Result updateMember(Member member) {
        if (member.getMemId() == null) {
            return Result.fail(ResponseEnum.PARAM_IS_NULL);
        }
        Member mem = memberMapper.selectById(member.getMemId());
        if (mem == null) {
            return Result.fail(ResponseEnum.UPDATE_ID_NOT_EXIST);
        } else {
            member.setMemPwd(Md5Tool.getMD5(member.getMemPwd()));
            int count = memberMapper.updateById(member);
            if (count == 1) {
                return Result.success(member);
            } else {
                return Result.fail(ResponseEnum.UPDATE_FAILED);
            }
        }
    }

    /**
     * 删除
     *
     * @param memId
     * @return
     */
    @Override
    public Result deleteMember(String memId) {
        Member mem = memberMapper.selectById(memId);
        if (mem == null) {
            return Result.fail(ResponseEnum.DELETE_ID_NOT_EXIST);
        } else {
//             逻辑应使用update代替delete
            int count = memberMapper.deleteById(memId);
            if (count == 1) {
                return Result.success(mem);
            } else {
                return Result.fail(ResponseEnum.DELETE_FAILED);
            }
        }
    }

    /**
     * 查询网格员
     *
     * @return
     */
    @Override
    public Result<List<Member>> selectGrid() {
        LambdaQueryWrapper<Member> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Member::getRoleId, 2);
        wrapper.orderByAsc(Member::getMemState);
        List<Member> list = memberMapper.selectList(wrapper);
        if (list != null) {
            return Result.success(list);
        }
        return Result.fail(ResponseEnum.SELECT_FAILED);
    }

    /**
     * 分页查询网格员
     *
     * @param pageInfo
     * @return
     */
    @Override
    public Result selectGridPage(PageInfo pageInfo) {
        Page<Member> page = new Page<>(pageInfo.getCurrentPage(), pageInfo.getPageSize());
        LambdaQueryWrapper<Member> wrapper = new LambdaQueryWrapper<>();
        wrapper.ne(Member::getMemState, 0);
        wrapper.eq(Member::getRoleId, 2);
        IPage<Member> iPage = memberMapper.selectPage(page, wrapper);
        return Result.success(iPage);
    }

    /**
     * 网格员分配
     *
     * @param memId
     * @return
     */
    @Override
    public Result updateAssign(Integer memId) {
        Member member = new Member();
        member.setMemId(memId);
        member.setMemState(2);
        int count = memberMapper.updateById(member);
        if (count == 1) {
            return Result.success(member);
        } else if (count == 0) {
            return Result.fail(ResponseEnum.GRIDER_NOT_EXIST);
        } else {
            return Result.fail(ResponseEnum.UPDATE_FAILED);
        }
    }

    /**
     * 根据id查询
     *
     * @param memId
     * @return
     */
    @Override
    public Result<Member> selectById(Integer memId) {
        if (memId == null) {
            return Result.fail(ResponseEnum.PARAM_IS_NULL);
        }
        Member member = memberMapper.selectById(memId);
        if (member != null) {
            member.setMemPwd("");
            return Result.success(member);
        } else {
            return Result.fail(ResponseEnum.SELECT_ID_NOT_EXIST);
        }
    }

    /**
     * 根据角色查询数量
     *
     * @param roleId
     * @return
     */
    @Override
    public Result selectCount(Integer roleId) {
        LambdaQueryWrapper<Member> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Member::getRoleId, roleId);
        return Result.success(memberMapper.selectCount(wrapper));
    }

    /**
     * 网格员自动分配
     *
     * @param location
     * @return
     */
    @Override
    public Result selectAutoAssign(String location) {
        //有bug（）
        String[] split = location.split("/");
        if (split == null || split.length == 0) {
            return Result.fail(ResponseEnum.PARAM_IS_NULL);
        }
        Member member = null;
        for (int i = split.length - 1; i >= 0; i--) {
            LambdaQueryWrapper<Member> wrapper = new LambdaQueryWrapper<>();
            wrapper.like(Member::getWorkProvince, split[i]);
            wrapper.ne(Member::getMemState, 0);
            wrapper.eq(Member::getRoleId, 2);
            wrapper.orderByAsc(Member::getMemState);
            member = memberMapper.selectOne(wrapper);
            if (member != null) {
                break;
            }
        }
        if (member != null) {
            return Result.success(member.getMemId());
        } else {
            return Result.fail(ResponseEnum.GRIDER_NOT_EXIST);
        }
    }
}
